function createShader(gl, type, source) {
    // 2.1创建对应类型的shader
    const shader = gl.createShader(type);
    // 2.2给shader添加数据源
    gl.shaderSource(shader, source);
    // 2.3编译shader
    gl.compileShader(shader);

    const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (success) {
        return shader;
    }
    gl.deleteShader(shader);
}

function createProgram(gl, vertexShader, fragmentShader) {
    // 3.1创建program
    const program = gl.createProgram();
    // 3.2添加顶点着色器
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    // 3.3添加片段着色器
    gl.linkProgram(program);
    const success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (success) {
        return program;
    }
    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
}

// 返回 0 到 range 范围内的随机整数
function randomInt(range) {
    return Math.floor(Math.random() * range);
}

function main() {
    // 1.创建glcontext
    var canvas = document.querySelector('#glcanvas');
    var gl = canvas.getContext('webgl');
    if (!gl) {
        return;
    }

    // 2.创建顶点着色器和片段着色器
    // 获取GLSL着色器strings
    const vertexShaderSource = document.querySelector("#vertex-shader").text;
    const fragmentShaderSource = document.querySelector("#fragment-shader").text;
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
    // 3.链接两个着色器到program
    const program = createProgram(gl, vertexShader, fragmentShader);

    // 4.告诉顶点数据的位置在哪儿
    const positionAttriabute = gl.getAttribLocation(program, "a_position");
    var colorLocation = gl.getAttribLocation(program, "a_color");

    var resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
    // lookup uniforms
    var matrixLocation = gl.getUniformLocation(program, "u_matrix");

    // 5.初始化缓冲区
    // 5.1创建缓冲区
    const positionBuffer = gl.createBuffer();

    //5.2将positionBuffer绑定到ARRAY_BUFFER(可以将其视为ARRAY_BUFFER=PositionBuffer)
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

    // 5.3创建一个包含三角形顶点的数组
    var positions = [
        0, 0,
        300, 0,
        0, 300,
        0, 300,
        300, 0,
        300, 300
    ];

    // 5.4将数据写入缓冲区,通过绑定点向缓冲区中存放数据
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

    // Create a buffer for the colors.
    var colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    // Set the colors.
    setColors(gl);

    //创建ui
    var translation = [0, 0];
    var angleInRadians = 0;
    var scale = [1, 1];

    drawScene();

    webglLessonsUI.setupSlider("#x", { value: translation[0], slide: updatePosition(0), max: gl.canvas.width });
    webglLessonsUI.setupSlider("#y", { value: translation[1], slide: updatePosition(1), max: gl.canvas.height });
    webglLessonsUI.setupSlider("#angle", { slide: updateAngle, max: 360 });
    webglLessonsUI.setupSlider("#scaleX", { value: scale[0], slide: updateScale(0), min: -5, max: 5, step: 0.01, precision: 2 });
    webglLessonsUI.setupSlider("#scaleY", { value: scale[1], slide: updateScale(1), min: -5, max: 5, step: 0.01, precision: 2 });

    function updatePosition(index) {
        return function (event, ui) {
            translation[index] = ui.value;
            drawScene();
        };
    }

    function updateAngle(event, ui) {
        var angleInDegrees = 360 - ui.value;
        angleInRadians = angleInDegrees * Math.PI / 180;
        drawScene();
    }

    function updateScale(index) {
        return function (event, ui) {
            scale[index] = ui.value;
            drawScene();
        };
    }

    function drawScene() {
        // 6.绘制
        // 重置画布大小
        webglUtils.resizeCanvasToDisplaySize(gl.canvas);
        // 6.2.1设置视口
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
        // 6.2.2清空画布
        gl.clearColor(1, 0, 0, 0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 6.2.3告诉它用我们之前写好的着色程序（一个着色器对）
        gl.useProgram(program);


        // 6.2.4启用属性
        gl.enableVertexAttribArray(positionAttriabute);
        // 6.2.5绑定数据，告诉属性如何从positionBuffer（ARRAY_BUFFER）中获取数据
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        var size = 2;          // 每次迭代的组件数为2
        var type = gl.FLOAT;   // 数据为32位浮点数
        var normalize = false; // 不对数据进行归一化
        var stride = 0;        // 0 = 每次迭代移动 size * sizeof(type) 以获取下一个位置
        var offset = 0;        // 从缓冲区的开头开始
        gl.vertexAttribPointer(
            positionAttriabute, size, type, normalize, stride, offset);

        // Turn on the color attribute
        gl.enableVertexAttribArray(colorLocation);

        // Bind the color buffer.
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);

        // Tell the color attribute how to get data out of colorBuffer (ARRAY_BUFFER)
        var size = 4;          // 4 components per iteration
        var type = gl.FLOAT;   // the data is 32bit floats
        var normalize = false; // don't normalize the data
        var stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
        var offset = 0;        // start at the beginning of the buffer
        gl.vertexAttribPointer(
            colorLocation, size, type, normalize, stride, offset);


        // Compute the matrix
        debugger
        var matrix = m3.projection(gl.canvas.clientWidth, gl.canvas.clientHeight);
        matrix = m3.translate(matrix, translation[0], translation[1]);
        matrix = m3.rotate(matrix, angleInRadians);
        matrix = m3.scale(matrix, scale[0], scale[1]);

        // Set the matrix.
        gl.uniformMatrix3fv(matrixLocation, false, matrix);


        gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
        // gl.uniform4f(colorUniformLocation, 1, 0, 0, 1);
        // 6.2.6绘制
        gl.drawArrays(gl.TRIANGLES, 0, 6);
    }
}

function setColors(gl) {
    // Pick 2 random colors.
    var r1 = Math.random();
    var b1 = Math.random();
    var g1 = Math.random();
    var r2 = Math.random();
    var b2 = Math.random();
    var g2 = Math.random();

    gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array(
            [
                Math.random(), Math.random(), Math.random(), 1,
                Math.random(), Math.random(), Math.random(), 1,
                Math.random(), Math.random(), Math.random(), 1,
                Math.random(), Math.random(), Math.random(), 1,
                Math.random(), Math.random(), Math.random(), 1,
                Math.random(), Math.random(), Math.random(), 1
            ]),
        gl.STATIC_DRAW);
}

main()